{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "#load \"..\\Extension\\LoadBaseTool.csx\"\n",
    "using BaseTool;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`{}`可以理解为是一个非`null`的对象\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "False\n",
      "True\n",
      "False\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "bool? _flag = null;\n",
    "\n",
    "Console.WriteLine(_flag is {});     // false\n",
    "Console.WriteLine(_flag is bool);   // false\n",
    "Console.WriteLine(_flag is null);   // true\n",
    "Console.WriteLine(_flag is true);   // false\n",
    "Console.WriteLine(_flag is false);  // false"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n",
      "False\n",
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "bool? _flag = true;\n",
    "\n",
    "Console.WriteLine(_flag is {});     // True\n",
    "Console.WriteLine(_flag is bool);   // True\n",
    "Console.WriteLine(_flag is null);   // False\n",
    "Console.WriteLine(_flag is true);   // True\n",
    "Console.WriteLine(_flag is false);  // False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n",
      "False\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "bool? _flag = false;\n",
    "\n",
    "Console.WriteLine(_flag is {});     // True\n",
    "Console.WriteLine(_flag is bool);   // True\n",
    "Console.WriteLine(_flag is null);   // False\n",
    "Console.WriteLine(_flag is true);   // True\n",
    "Console.WriteLine(_flag is false);  // False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\r\n"
     ]
    }
   ],
   "source": [
    "Console.WriteLine(\"string\" is {});     // True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对象属性 `is` 比较\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello World\n",
      "Hello World\n"
     ]
    }
   ],
   "source": [
    "class Person\n",
    "{\n",
    "    public string FirstName {get;set;} = \"Tim\";\n",
    "    public string LastName {get;set;} = \"Cook\";\n",
    "\n",
    "    public Address Home {get;set;} = new Address();\n",
    "}\n",
    "\n",
    "class Address{\n",
    "    public string City {get;set;} = \"Dallas\";\n",
    "    public string State {get;set;} = \"TX\";\n",
    "}\n",
    "\n",
    "Person _person = new();\n",
    "if(_person is { FirstName:\"Tim\" })\n",
    "{\n",
    "    Console.WriteLine($\"Hello World\");\n",
    "}\n",
    "\n",
    "if(_person is { FirstName:\"Tim\", Home.City:\"Dallas\"})\n",
    "{\n",
    "    Console.WriteLine($\"Hello World\");\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello World\r\n"
     ]
    }
   ],
   "source": [
    "class Person\n",
    "{\n",
    "    public bool IsPerson {get ;set;} = true;\n",
    "    public string FirstName => IsPerson ? \"Tim\" : throw new Exception();\n",
    "    public string LastName => IsPerson ? \"Cook\": throw new Exception();\n",
    "}\n",
    "\n",
    "Person _person = new();\n",
    "if(_person is { IsPerson: true, FirstName:\"Tim\" })\n",
    "{\n",
    "    Console.WriteLine($\"Hello World\");\n",
    "}\n",
    "\n",
    "// 此处使用了短路逻辑\n",
    "// 如果 IsPerson 为 false, 那么就不会执行 FirstName 的取值操作，所以不会抛出异常\n",
    "if(_person is { IsPerson: false, FirstName:\"Tim\"})\n",
    "{\n",
    "    Console.WriteLine($\"Hello World\");\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "prime number\n",
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "int _number = 3;\n",
    "\n",
    "if(_number is 2 or 3 or 5 or 7) \n",
    "{\n",
    "    Console.WriteLine(\"prime number\");\n",
    "}\n",
    "\n",
    "(_number is >= 2).Dump();  // 和_numer >= 2一样，只是使用模式匹配来做\n",
    "(_number is >= 2 and <=5 ).Dump();  // 和 2 <= _numer && _number <= 5一样，只是使用模式匹配来做"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对 Tuple 进行批量比较，这里是 is 模式匹配中包含两个条件，分别对于第一个元素和第二个元素进行比较。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n",
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "(int, int) _tuple = (3, 5);\n",
    "\n",
    "(_tuple is (>2, <4)).Dump(); // 3 > 2 but 5 > 4\n",
    "(_tuple is (>2, >4)).Dump(); // 3 > 2 and 5 > 4\n",
    "(_tuple is (>2, _)).Dump();  // 表示忽略对5的比较\n",
    "(_tuple is (>2, not 4)).Dump();  // 5 != 4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`1 = 1`, `3 not 2`, `5 < 6`, `7 >= 6`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\r\n"
     ]
    }
   ],
   "source": [
    "byte[] _array = [1, 3, 5, 7];\n",
    "(_array is [1, not 2, <6, >=6]).Dump();"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`is not` 判断中如果包含 `or`，则需要用括号括起来。如果不括起来，相当于先判断 `is not`，再判断 `is`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n",
      "True\n",
      "True\n",
      "----------------\n",
      "False\n",
      "True\n",
      "True\n",
      "True\n",
      "----------------\n",
      "False\n",
      "True\n",
      "True\n",
      "True\n",
      "===============\n",
      "True\n",
      "False\n",
      "False\n",
      "False\n",
      "----------------\n",
      "True\n",
      "False\n",
      "True\n",
      "False\n",
      "----------------\n",
      "True\n",
      "False\n",
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "public enum Type\n",
    "{\n",
    "    List = 0b_000000,\n",
    "    Binary = 0b_001000,\n",
    "}\n",
    "\n",
    "public class SECSItem\n",
    "{\n",
    "    private Type m_Type;\n",
    "    public required Type Type\n",
    "    {\n",
    "        get => m_Type;\n",
    "        set => m_Type = value;\n",
    "    }\n",
    "}\n",
    "\n",
    "SECSItem _item = new(){ Type = Type.List};\n",
    "\n",
    "Console.WriteLine($\"{_item is {Type: Type.Binary}}\");   // false\n",
    "Console.WriteLine($\"{_item is {Type: Type.List}}\");     // true\n",
    "Console.WriteLine($\"{_item is {Type: Type.Binary or Type.List}}\");          // true\n",
    "Console.WriteLine($\"{_item is {Type: Type.List or Type.Binary}}\");          // true\n",
    "\n",
    "Console.WriteLine(\"----------------\");\n",
    "\n",
    "Console.WriteLine($\"{_item.Type is Type.Binary}\");        // false\n",
    "Console.WriteLine($\"{_item.Type is Type.List}\");          // true\n",
    "Console.WriteLine($\"{_item.Type is Type.Binary or Type.List}\");          // true\n",
    "Console.WriteLine($\"{_item.Type is Type.List or Type.Binary}\");          // true\n",
    "\n",
    "Console.WriteLine(\"----------------\");\n",
    "\n",
    "Console.WriteLine($\"{_item is {Type: Type.Binary}}\");        // false\n",
    "Console.WriteLine($\"{_item is {Type: Type.List}}\");          // true\n",
    "Console.WriteLine($\"{_item is {Type: Type.Binary} or {Type: Type.List}}\");          // true\n",
    "Console.WriteLine($\"{_item is {Type: Type.List} or {Type: Type.Binary}}\");          // true\n",
    "\n",
    "Console.WriteLine(\"===============\");\n",
    "\n",
    "Console.WriteLine($\"{_item is not {Type: Type.Binary}}\");        // true\n",
    "Console.WriteLine($\"{_item is not {Type: Type.List}}\");          // false\n",
    "Console.WriteLine($\"{_item is not {Type: Type.Binary or Type.List}}\");          // false\n",
    "Console.WriteLine($\"{_item is not {Type: Type.List or Type.Binary}}\");          // false\n",
    "\n",
    "Console.WriteLine(\"----------------\");\n",
    "\n",
    "// 注意此处的结果，是错误的\n",
    "Console.WriteLine($\"{_item.Type is not Type.Binary}\");        // true\n",
    "Console.WriteLine($\"{_item.Type is not Type.List}\");          // false\n",
    "Console.WriteLine($\"{_item.Type is not Type.Binary or Type.List}\");          // true\n",
    "Console.WriteLine($\"{_item.Type is not Type.List or Type.Binary}\");          // false\n",
    "\n",
    "Console.WriteLine(\"----------------\");\n",
    "\n",
    "// 注意此处的结果，是错误的\n",
    "Console.WriteLine($\"{_item is not {Type: Type.Binary}}\");        // true\n",
    "Console.WriteLine($\"{_item is not {Type: Type.List}}\");          // false\n",
    "Console.WriteLine($\"{_item is not {Type: Type.Binary} or {Type: Type.List}}\"); // true\n",
    "Console.WriteLine($\"{_item is not {Type: Type.List} or {Type: Type.Binary}}\"); // false\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".NET (C#)",
   "language": "C#",
   "name": ".net-csharp"
  },
  "language_info": {
   "name": "polyglot-notebook"
  },
  "polyglot_notebook": {
   "kernelInfo": {
    "defaultKernelName": "csharp",
    "items": [
     {
      "aliases": [],
      "languageName": "csharp",
      "name": "csharp"
     }
    ]
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
